﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Web.Mvc;
using VideoSeller.Business.Data;
using VideoSeller.Business.Data.Enums;
using VideoSeller.Business.Models;
using VideoSeller.Core.Interfaces;

namespace VideoSeller.Web.Controllers
{
	public class PayPalController : BaseController
	{
		private readonly SettingsModel _settingsModel;
		private readonly PostingModel _postingModel;
		private readonly CategoryModel _categoryModel;
		private readonly IDatabaseSettingsProvider _databaseSettingsProvider;

		public PayPalController(PostingModel postingModel, SettingsModel settingsModel, CategoryModel categoryModel, IDatabaseSettingsProvider databaseSettingsProvider)
		{
			_postingModel = postingModel;
			_settingsModel = settingsModel;
			_categoryModel = categoryModel;
			_databaseSettingsProvider = databaseSettingsProvider;
		}

		public ActionResult IPN()
		{
			var sandbox = _databaseSettingsProvider.PayPalEnvironment.ToLower() == "sandbox";
			var formVals = new Dictionary<string, string> {{"cmd", "_notify-validate"}};
			var response = GetPayPalResponse(formVals, sandbox);

			if (response == "VERIFIED")
			{
				var amountPaid = Request["mc_gross"];              
				var userIdValue = Request["custom"];
				var currencyCode = Request["mc_currency"];
				decimal refillAmount;
              
                /*Hapaniuk changes at 17.08.2013*/
                var amountFee = Request["mc_fee"];
                decimal feeAmount;
                /**/
				
                Guid userId;
				var exchangeRate = 100; // default

				if (currencyCode.ToLower() == "USD".ToLower())
				{
					var setting = _settingsModel.GetSetting("UsdToVsl");

					if (setting != null)
					{
						exchangeRate = int.Parse(setting.Value);
					}
				}
                exchangeRate = 1; //Vladimir - only USD

                /*Hapaniuk changes at 17.08.2013
                 * 
                 add: && decimal.TryParse(amountFee, out feeAmount)
                 change: refillAmount -> (refillAmount - feeAmount )
                 */

                if (decimal.TryParse(amountPaid, out refillAmount) && decimal.TryParse(amountFee, out feeAmount) && Guid.TryParse(userIdValue, out userId))
				{
                    _postingModel.AddFinanceOperation(userId, (refillAmount - feeAmount) * exchangeRate, FinanceOperation.Refill, "Paypal fee = " + (feeAmount * exchangeRate).ToString()+" $");
				}
			}

			return new EmptyResult();
		}

		[NonAction]
		private string GetPayPalResponse(Dictionary<string, string> formVals, bool useSandbox)
		{
			var paypalUrl = useSandbox
				                ? "https://www.sandbox.paypal.com/cgi-bin/webscr"
				                : "https://www.paypal.com/cgi-bin/webscr";
			var req = (HttpWebRequest) WebRequest.Create(paypalUrl);
			req.Method = "POST";
			req.ContentType = "application/x-www-form-urlencoded";

			var param = Request.BinaryRead(Request.ContentLength);
			var strRequest = Encoding.ASCII.GetString(param);
			var sb = new StringBuilder();
			sb.Append(strRequest);

			foreach (var key in formVals.Keys)
			{
				sb.AppendFormat("&{0}={1}", key, formVals[key]);
			}

			strRequest += sb.ToString();
			req.ContentLength = strRequest.Length;

			var response = "";

			using (var streamOut = new StreamWriter(req.GetRequestStream(), Encoding.ASCII))
			{

				streamOut.Write(strRequest);
				streamOut.Close();

				using (var streamIn = new StreamReader(req.GetResponse().GetResponseStream()))
				{
					response = streamIn.ReadToEnd();
				}
			}

			return response;
		}
	}
}